const {
	DayLine
} = require('lg-entity');
const {
	Service
} = require('uni-cloud-router');
const {
	getStockDWMKLine
} = require("lg-request-stock");
const {
	parser,
	success,
	exception,
	error,
	typeOf,
	Clock,
	timingLogger,
	StatusEnum,
	isArray,
	isUndefined,
	isNumber
} = require("lg-utils");
const {
	forEachCollection,
	pushLineitem,
	getCollForAllByField,
	updateFieldsForColl
} = require("lg-utils-db");
const db = uniCloud.database();
const dbCmd = db.command;

const STOCK_DAY_LINE_COLL = db.collection("stock-day-line");
const stockWeekLineColl = db.collection("stock-week-line");
const stockMonthLineColl = db.collection("stock-month-line");
const templateColl = db.collection("template");
module.exports = class LineService extends Service {
	async xxx() {
		try {
			return "xxxxxxx"
		} catch (e) {
			throw e
		}

	}
	// 移除掉日期重复line数组项数据;
	async clearRepeatLineForDay() {
		try {
			return await forEachCollection({
					collection: STOCK_DAY_LINE_COLL,
					pageSize: 50,
					cycle: 0
				},
				async (iter) => {
					const {
						symbol,
						line
					} = iter;
					let tempArr = [];
					let dates = [];
					for (let lineIter of line) {
						const date = lineIter[0];
						if (!dates.includes(date)) {
							tempArr.push(lineIter);
							dates.push(date);
						}
					}

					if (line.length && line.length > tempArr.length) {
					 const {data:updateCount} = await updateFieldsForColl({
							collection: STOCK_DAY_LINE_COLL,
							where:{
								symbol
							},
							updater:{
								line:tempArr
							}
						}) || {};
						if(isNumber(updateCount) && updateCount > 0){
							return symbol
						}
						
					}



				}
			)
		} catch (e) {
			throw e
		}

	}
	// 日线添加新数据项;
	async addIterForDay(inserter = {}) {
		try {
			let insertArr = [];
			if (isArray(inserter)) {
				insertArr = inserter;
			} else {
				insertArr = [inserter];
			}
			const {
				inserted
			} = await STOCK_DAY_LINE_COLL.add(insertArr) || {};
			if (isNumber(inserted)) {
				return success(inserted);
			} else {
				return error("日线集合添加数据项数据库操作异常;");
			}
		} catch (e) {
			return e
		}

	}

	// 获取K线数据;
	async getLineIter({
		type = "",
		symbol = "",
		cycle = 0
	} = {}) {
		try {
			const fetchRes = await getStockDWMKLine({
				type,
				symbol,
				cycle
			});
			const {
				status,
				data
			} = fetchRes || {};
			if (StatusEnum.SUCCESS === status) {
				const {
					data: {
						[symbol]: {
							[cycle == 0 ? type : `qfq${type}`]: list
						} = {}
					} = {}
				} = data || {};
				return success(cycle === 0 ? list[0] : list);
			} else {
				return error("远程调取K线数据请求异常.", fetchRes);
			}

		} catch (e) {
			return error("获取K线数据异常.", e);
		}

	}
	// 更新指定集合的数据项;
	async updateCollectionData({
		collection = {},
		where = {},
		updater = {}
	} = {}) {
		try {
			const {
				affectedDocs,
				updated
			} = await collection.where(where).update(updater) || {};
			if (typeOf(affectedDocs, StatusEnum.UNDEFINED)) {
				return error("更新操作请求异常", {
					affectedDocs: undefined
				});
			} else {
				return success(updated);
			}
		} catch (e) {
			return error("更新集合数据异常.", e);
		}
	}
	// 更新日线Line数据;
	updateLineDataForDay() {

	}
	// 更新指定集合的 line 数据;
	async updateKline({
		type = "",
		collection = {},
		symbol = "",
		cycle = 0
	}) {
		const {
			success: iterSucc,
			data: iterData,
			errorMessage: iterErro
		} = await this.getLineIter({
			type,
			cycle,
			symbol
		});
		if (iterSucc) {
			const {
				success: updateSucc,
				data: updateIter,
				errorMessage: updateErro
			} = await this.updateCollectionData({
				collection,
				where: {
					symbol
				},
				updater: {
					line: iterData
				}
			});
			if (updateSucc) {
				return success(updateIter);
			} else {
				return error(updateErro);
			}
		} else {
			return error(iterErro);
		}
	}
	// 对比 stock 集合 ,更新line集合数据项;
	async refreshSymbolsWithStockByDiff() {
		try {

			const {
				data: dayLineList,
				hasErrors: allDayLineError,
				errorMessage: allDayLineErrMsg,
				exceptionData: allDayLineExceData
			} = await getCollForAllByField({
				collection: STOCK_DAY_LINE_COLL,
				field: {
					symbol: true,
					code: true,
					name: true
				}
			}) || {};

			if (allDayLineError) {
				return error(errorMessage, exceptionData);
			}

			const {
				result: {
					data: stockBaseList,
					hasErrors: allStockBaseError,
					errorMessage: allStockBaseErrMsg,
					exceptionData: allStockBaseExceData
				}
			} =
			await uniCloud.callFunction({
				name: "stock",
				data: {
					action: "common/getStockBaseAllByFields",
					data: {
						symbol: true,
						code: true,
						name: true,
					}
				}
			}) || {};

			if (allStockBaseError) {
				return error(allStockBaseErrMsg, allStockBaseExceData);
			}

			if (dayLineList.length && stockBaseList.length) {
				const symbols = dayLineList.map(mi => mi.symbol);
				const diffList = stockBaseList.filter(fi => {
					const {
						symbol
					} = fi;
					return !symbols.includes(symbol);
				})
				if (diffList && diffList.length) {
					const diffDayLineList = diffList.map(mi => {
						return new DayLine({
							...mi
						});
					});
					const {
						errorMessage: addDayIterErrMsg,
						exceptionData: addDayIterExceData,
						hasErrors: addDayIterError
					} = await this.addIterForDay(diffDayLineList) || {};
					if (addDayIterError) {
						return error(addDayIterErrMsg, addDayIterExceData);
					}
				}
				return success(diffList);
			} else {
				return error("获取集合项数据异常;")
			}

		} catch (e) {
			throw e;
		}
	}
	// 循环k线集合,更新line字段数据;
	async updateDayKLineAll() {
		try {
			return await forEachCollection({
				collection: STOCK_DAY_LINE_COLL,
				pageSize: 100,
				lastId: "",
				cycle: 0
			}, async (iter, page, index) => {
				const {
					symbol,
					_id: id
				} = iter;

				const {
					success: updaSucc,
					data: updaData,
					errorMessage: updaErro
				} = await this.updateKline({
					collection: STOCK_DAY_LINE_COLL,
					symbol,
					type: "day",
					cycle: 640
				});
				console.log(page, ">", index, id);
				if (updaSucc) {
					return updaData

				} else {
					throw {
						id,
						errMeg: updaErro
					}
				}
			})

		} catch (e) {
			throw e
		}

	}
}
